package com.mdd.admin.service.finance;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mdd.admin.vo.finance.FinanceVo;
import com.mdd.common.constant.GlobalConstant;
import com.mdd.common.entity.order.Order;
import com.mdd.common.entity.refund.OrderRefund;
import com.mdd.common.enums.OrderPayStatusEnum;
import com.mdd.common.enums.OrderRefundStatusEnum;
import com.mdd.common.mapper.order.OrderMapper;
import com.mdd.common.mapper.refund.OrderRefundMapper;
import com.mdd.common.utils.TimeUtil;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * @ClassName FinanceImpl
 * @Description
 * @Autore Slien.zuo
 * @Date 2022/10/13 19:19
 * @Version 1.0
 **/
@Service
public class FinanceImpl implements IFinanceService {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderRefundMapper orderRefundMapper;

    @Override
    public FinanceVo statisticsFinance() {
        FinanceVo vo = new FinanceVo();
        BigDecimal totalAmount = BigDecimal.ZERO;
        int totalOrder = 0;
        BigDecimal totalRefundAmount = BigDecimal.ZERO;
        BigDecimal waitRefundAmount = BigDecimal.ZERO;
        // 订单
        LambdaQueryWrapper<Order> order = new LambdaQueryWrapper<>();
        order.eq(Order::getPayStatus, OrderPayStatusEnum.PAY.getStatus());
        order.eq(Order::getIsDelete, GlobalConstant.NOT_DELETE);
        List<Order> list = orderMapper.selectList(order);
        if (CollectionUtils.isNotEmpty(list)) {
            for (Order model : list) {
                totalAmount = totalAmount.add(model.getTotalAmount());
                totalOrder = totalOrder + model.getTotalNum();
            }
        }
        // 退款
        LambdaQueryWrapper<OrderRefund> refund = new LambdaQueryWrapper<>();
        List<OrderRefund> orderRefunds = orderRefundMapper.selectList(refund);
        if (CollectionUtils.isNotEmpty(orderRefunds)) {
            for (OrderRefund orderRefund : orderRefunds) {
                if (OrderRefundStatusEnum.SUCCESS.getStatus() == orderRefund.getRefundStatus()) {
                    totalRefundAmount = totalRefundAmount.add(orderRefund.getRefundAmount());
                }
                if (OrderRefundStatusEnum.REFUNDING.getStatus() == orderRefund.getRefundStatus()
                        || OrderRefundStatusEnum.FAILURE.getStatus() == orderRefund.getRefundStatus()) {
                    waitRefundAmount = waitRefundAmount.add(orderRefund.getRefundAmount());
                }
            }
        }
        vo.setTotalAmount(totalAmount);
        vo.setTotalOrder(totalOrder);
        vo.setTotalRefundAmount(totalRefundAmount);
        vo.setWaitRefundAmount(waitRefundAmount);
        return vo;
    }

    /**
     * 该方法通过时间用来统计财务
     * @param map 开始时间和结束时间
     * @return 返回在指定时间的财务
     */
    @Override
    public FinanceVo conditionStatisticsFinance(HashMap<String, String> map) {
        // 格式 yyyy-MM-dd
        String startTime = map.get("startTime");
        String endTime = map.get("endTime");
        Assert.notEmpty(startTime, "startTime为空");
        Assert.notEmpty(endTime, "endTime为空");
        Long startDate = TimeUtil.dateToTimestamp(startTime);
        Long endDate = TimeUtil.dateToTimestamp(endTime);
        endDate += 86400;
        // 订单
        List<Order> orders = orderMapper.selectList(new LambdaQueryWrapper<Order>()
                .eq(Order::getIsDelete, GlobalConstant.NOT_DELETE)
                .eq(Order::getPayStatus, OrderPayStatusEnum.PAY.getStatus())
                .between(Order::getCreateTime, startDate, endDate));
        BigDecimal totalAmount = BigDecimal.ZERO;
        int totalOrder = 0;
        for (Order order : orders) {
            if(Objects.nonNull(order.getTotalAmount())){
                totalOrder += order.getTotalNum();
                totalAmount = totalAmount.add(order.getTotalAmount());
            }
        }
        FinanceVo financeVo = new FinanceVo();
        // 设置累计营业额
        financeVo.setTotalAmount(totalAmount);
        // 设置成交订单
        financeVo.setTotalOrder(totalOrder);
        BigDecimal totalRefundAmount = BigDecimal.ZERO;
        BigDecimal waitRefundAmount = BigDecimal.ZERO;
        List<OrderRefund> orderRefunds = orderRefundMapper.selectList(new LambdaQueryWrapper<OrderRefund>()
                .between(OrderRefund::getCreateTime, startDate, endDate));
        for (OrderRefund orderRefund : orderRefunds) {
            if(OrderRefundStatusEnum.SUCCESS.getStatus() == orderRefund.getRefundStatus()) {
                totalRefundAmount = totalRefundAmount.add(orderRefund.getRefundAmount());
            } else if(OrderRefundStatusEnum.REFUNDING.getStatus() == orderRefund.getRefundStatus()
                    || OrderRefundStatusEnum.FAILURE.getStatus() == orderRefund.getRefundStatus()) {
                waitRefundAmount = waitRefundAmount.add(orderRefund.getRefundAmount());
            }
        }
        financeVo.setTotalRefundAmount(totalRefundAmount);
        financeVo.setWaitRefundAmount(waitRefundAmount);
        return financeVo;
    }

    /**
     * 返回订单和退款订单的数据
     * @param map 开始时间和结束时间
     * @return 返回订单和退款订单的数据
     */
    @Override
    public Map<String, Object> getOrderListByCondition(Map<String, String> map) {
        HashMap<String, Object> hashMap = new HashMap<>();
        // 格式 yyyy-MM-dd
        String startTime = map.get("startTime");
        String endTime = map.get("endTime");
        Assert.notEmpty(startTime, "startTime为空");
        Assert.notEmpty(endTime, "endTime为空");
        Long startDate = TimeUtil.dateToTimestamp(startTime);
        Long endDate = TimeUtil.dateToTimestamp(endTime);
        endDate += 86400;
        // 订单
        List<Order> orders = orderMapper.selectList(new LambdaQueryWrapper<Order>()
                .eq(Order::getIsDelete, GlobalConstant.NOT_DELETE)
                .eq(Order::getPayStatus, OrderPayStatusEnum.PAY.getStatus())
                .between(Order::getCreateTime, startDate, endDate));
        List<OrderRefund> orderRefunds = orderRefundMapper.selectList(new LambdaQueryWrapper<OrderRefund>()
                .between(OrderRefund::getCreateTime, startDate, endDate));
        hashMap.put("orders", orders);
        hashMap.put("orderRefunds", orderRefunds);
        return hashMap;
    }
}
